#include "opencv_hough.h"

#include<opencv2\opencv.hpp>   
#include<opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>

using namespace std;
using namespace cv;

void doOpencvHough1()
{
	Mat srcImage = imread("test.jpg");
	imshow("Src Pic", srcImage);

	Mat midImage, dstImage;
	//边缘检测
	Canny(srcImage, midImage, 50, 200, 3);
	imshow("Canny", midImage);
	//灰度化
	cvtColor(midImage, dstImage, CV_GRAY2BGR);
	imshow("CV_GRAY2BGR", dstImage);
	// 定义矢量结构存放检测出来的直线
	vector<Vec2f> lines;
	//通过这个函数，我们就可以得到检测出来的直线集合了
	HoughLines(midImage, lines, 1, CV_PI / 180, 90, 0, 0);
	//这里注意第五个参数，表示阈值，阈值越大，表明检测的越精准，速度越快，得到的直线越少（得到的直线都是很有把握的直线）
	//这里得到的lines是包含rho和theta的，而不包括直线上的点，所以下面需要根据得到的rho和theta来建立一条直线

	//依次画出每条线段
	for (size_t i = 0; i < lines.size(); i++)
	{
		float rho = lines[i][0]; //就是圆的半径r
		float theta = lines[i][1]; //就是直线的角度

		float angle = theta / CV_PI * 180;  // 角度
		Point pt1, pt2;
		double a = cos(theta), b = sin(theta);
		double x0 = a * rho, y0 = b * rho;
		pt1.x = cvRound(x0 + 1000 * (-b));
		pt1.y = cvRound(y0 + 1000 * (a));
		pt2.x = cvRound(x0 - 1000 * (-b));
		pt2.y = cvRound(y0 - 1000 * (a));

		line(dstImage, pt1, pt2, Scalar(55, 100, 195), 1, LINE_AA); //Scalar函数用于调节线段颜色，就是你想检测到的线段显示的是什么颜色
		cout << "line " << i << ": " << "rho:" << rho << " theta:" << theta << endl;

	}

	imshow("HoughLines", midImage);
	imshow("line", dstImage);
	waitKey();
}





void doOpencvHough2()
{
	Mat srcImage = imread("test.jpg");
	imshow("Src Pic", srcImage);

	Mat midImage, dstImage;
	//边缘检测
	Canny(srcImage, midImage, 50, 200, 3);
	imshow("Canny", midImage);
	//灰度化
	cvtColor(midImage, dstImage, CV_GRAY2BGR);
	imshow("CV_GRAY2BGR", dstImage);
	
	vector<Vec4i> lines;
	//与HoughLines不同的是，HoughLinesP得到lines的是含有直线上点的坐标的，所以下面进行划线时就不再需要自己求出两个点来确定唯一的直线了
	HoughLinesP(midImage, lines, 1, CV_PI / 180, 80, 50, 10);//注意第五个参数，为阈值

	//依次画出每条线段
	for (size_t i = 0; i < lines.size(); i++)
	{
		Vec4i l = lines[i];

		line(dstImage, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(186, 88, 255), 1, LINE_AA); //Scalar函数用于调节线段颜色

	}

	imshow("HoughLinesP", midImage);
	imshow("line", dstImage);
	waitKey();

}


void doOpencvHough3()
{
	Mat srcImage = imread("test.jpg");
	Mat midImage, dstImage;//临时变量和目标图的定义  

	imshow("src", srcImage);

	//【3】转为灰度图，进行图像平滑  
	cvtColor(srcImage, midImage, CV_BGR2GRAY);//转化边缘检测后的图为灰度图  
	imshow("gray", midImage);
	GaussianBlur(midImage, midImage, Size(9, 9), 2, 2);
	imshow("GaussianBlur", midImage);

	//【4】进行霍夫圆变换  
	vector<Vec3f> circles;
	HoughCircles(midImage, circles, CV_HOUGH_GRADIENT, 1.5, 10, 200, 150, 0, 0); //注意第七的参数为阈值，可以自行调整，值越大，检测的圆更精准

	//【5】依次在图中绘制出圆  
	for (size_t i = 0; i < circles.size(); i++)
	{
		Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
		int radius = cvRound(circles[i][2]);
		//绘制圆心  
		circle(srcImage, center, 3, Scalar(0, 255, 0), -1, 8, 0);
		//绘制圆轮廓  
		circle(srcImage, center, radius, Scalar(155, 50, 255), 3, 8, 0);
	}

	//【6】显示效果图    
	imshow("HoughCircles", srcImage);

	waitKey(0);

}
